package com.fjnu.dao.impl;

import com.fjnu.dao.ArticleDao;
import com.fjnu.dto.ArticleConditionDto;
import com.fjnu.entity.Article;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;

import java.sql.PreparedStatement;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @desc:
 * @author: Ping
 * @date: 2025/10/17 9:53
 */

@Repository
public class ArticleDaoImpl implements ArticleDao {

    @Autowired
    JdbcTemplate jdbcTemplate;


    private ArticleRowMapper articleRowMapper = new ArticleRowMapper();


    @Override
    public int insert(Article article) {
        // 检查必填字段是否为空
        if (article.getUserId() == null || article.getTitle() == null ||
                article.getContent() == null || article.getCategoryId() == null) {
            return 0; // 插入失败
        }

        String sql = "INSERT INTO tb_article (user_id, title, content, category_id, create_time, update_time) " +
                "VALUES (?, ?, ?, ?, NOW(), NOW())";

        KeyHolder keyHolder = new GeneratedKeyHolder();
        int result = jdbcTemplate.update(connection -> {
            PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            ps.setInt(1, article.getUserId());
            ps.setString(2, article.getTitle());
            ps.setString(3, article.getContent());
            ps.setInt(4, article.getCategoryId());
            return ps;
        }, keyHolder);

        if (result > 0 && keyHolder.getKey() != null) {
            // 设置生成的ID到article对象中
            article.setId(keyHolder.getKey().intValue());
            return 1;
        }
        
        return 0;
    }

    @Override
    public int updateContent(Integer articleId, String newContent) {
        String sql = "UPDATE tb_article SET content = ?, update_time = NOW() WHERE id = ?";
        return jdbcTemplate.update(sql, newContent, articleId);
    }

    @Override
    public int updateTitle(Integer id, String newTitle) {
        String sql = "UPDATE tb_article SET title = ?, update_time = NOW() WHERE id = ?";
        return jdbcTemplate.update(sql, newTitle, id);
    }

    @Override
    public int updateByCondition(Integer id, ArticleConditionDto articleCondition) {
        // 构建动态SQL语句
        StringBuilder sqlBuilder = new StringBuilder("UPDATE tb_article SET ");
        boolean needComma = false;

        // 根据传入条件添加更新字段
        if (articleCondition.getTitle() != null) {
            sqlBuilder.append("title = ?");
            needComma = true;
        }
        if (articleCondition.getContent() != null) {
            if (needComma) sqlBuilder.append(", ");
            sqlBuilder.append("content = ?");
            needComma = true;
        }
        if (articleCondition.getStatus() != null) {
            if (needComma) sqlBuilder.append(", ");
            sqlBuilder.append("status = ?");
            needComma = true;
        }
        if (articleCondition.getCategoryId() != null) {
            if (needComma) sqlBuilder.append(", ");
            sqlBuilder.append("category_id = ?");
            needComma = true;
        }

        sqlBuilder.append(", update_time = NOW() WHERE id = ?");

        // 准备参数列表
        List<Object> params = new ArrayList<>();
        if (articleCondition.getTitle() != null) {
            params.add(articleCondition.getTitle());
        }
        if (articleCondition.getContent() != null) {
            params.add(articleCondition.getContent());
        }
        if (articleCondition.getStatus() != null) {
            params.add(articleCondition.getStatus());
        }
        if (articleCondition.getCategoryId() != null) {
            params.add(articleCondition.getCategoryId());
        }
        params.add(id);

        // 执行更新操作
        return jdbcTemplate.update(sqlBuilder.toString(), params.toArray());
    }

    @Override
    public int updateUpdateTime(Integer id, LocalDateTime updateTime) {
        String sql = "UPDATE tb_article SET update_time = ? WHERE id = ?";
        return jdbcTemplate.update(sql, updateTime, id);
    }

    @Override
    public int updateStatus(Integer id, Integer newStatus) {
        String sql = "UPDATE tb_article SET status = ?, update_time = NOW() WHERE id = ?";
        return jdbcTemplate.update(sql, newStatus, id);
    }

    @Override
    public int batchUpdateStatus(List<Integer> ids, Integer newStatus) {
        if (ids == null || ids.isEmpty()) {
            return 0;
        }

        // 构造占位符字符串: ?,?,?
        String placeholders = String.join(",", Collections.nCopies(ids.size(), "?"));
        String sql = "UPDATE tb_article SET status = ?, update_time = NOW() WHERE id IN (" + placeholders + ")";

        // 构造参数数组
        Object[] params = new Object[ids.size() + 1];
        params[0] = newStatus;
        for (int i = 0; i < ids.size(); i++) {
            params[i + 1] = ids.get(i);
        }

        return jdbcTemplate.update(sql, params);
    }

    @Override
    public int deleteById(Integer id) {
        String sql = "DELETE FROM tb_article WHERE id = ?";
        return jdbcTemplate.update(sql, id);
    }


    @Override
    public List<Article> selectByUserId(Integer userId) {
        String sql = "SELECT * FROM tb_article ta WHERE ta.user_id = ? ";
        return jdbcTemplate.query(sql, articleRowMapper, userId);
    }

    @Override
    public List<Article> selectByKeyWord(String keyword) {
        String sql = "SELECT * FROM tb_article ta WHERE ta.title LIKE ? OR ta.content LIKE ?";
        String keyWordLike = "%" + keyword + "%";
        return jdbcTemplate.query(sql, articleRowMapper, keyWordLike, keyWordLike);
    }

    @Override
    public List<Article> selectByTimePeriod(LocalDateTime startTime, LocalDateTime endTime) {
        if (startTime != null && endTime != null && startTime.isAfter(endTime))
            return null;
        String sql = "SELECT * FROM tb_article ta WHERE ta.create_time BETWEEN ? AND ?";
        return jdbcTemplate.query(sql, articleRowMapper, startTime, endTime);
    }

    @Override
    public List<Article> selectByTag(Integer tagId) {
        String sql = "SELECT DISTINCT ta.* FROM tb_article ta " +
                "INNER JOIN tb_article_tag tat ON ta.id = tat.article_id " +
                "WHERE tat.tag_id = ?";
        return jdbcTemplate.query(sql, articleRowMapper, tagId);
    }


    @Override
    public List<Article> selectByCategory(Integer categoryId) {
        String sql = "SELECT * FROM tb_article ta WHERE ta.category_id = ?";
        return jdbcTemplate.query(sql, articleRowMapper, categoryId);
    }
    
    @Override
    public Article selectById(Integer id) {
        String sql = "SELECT * FROM tb_article WHERE id = ?";
        List<Article> articles = jdbcTemplate.query(sql, articleRowMapper, id);
        return articles.isEmpty() ? null : articles.get(0);
    }
    
    @Override
    public int countByCondition(ArticleConditionDto articleCondition) {
        StringBuilder sqlBuilder = new StringBuilder("SELECT COUNT(*) FROM tb_article WHERE 1=1");
        List<Object> params = new ArrayList<>();
        
        if (articleCondition.getUserId() != null) {
            sqlBuilder.append(" AND user_id = ?");
            params.add(articleCondition.getUserId());
        }
        
        if (articleCondition.getTitle() != null && !articleCondition.getTitle().isEmpty()) {
            sqlBuilder.append(" AND title LIKE ?");
            params.add("%" + articleCondition.getTitle() + "%");
        }
        
        if (articleCondition.getContent() != null && !articleCondition.getContent().isEmpty()) {
            sqlBuilder.append(" AND content LIKE ?");
            params.add("%" + articleCondition.getContent() + "%");
        }
        
        if (articleCondition.getStatus() != null) {
            sqlBuilder.append(" AND status = ?");
            params.add(articleCondition.getStatus());
        }
        
        if (articleCondition.getCategoryId() != null) {
            sqlBuilder.append(" AND category_id = ?");
            params.add(articleCondition.getCategoryId());
        }
        
        return jdbcTemplate.queryForObject(sqlBuilder.toString(), Integer.class, params.toArray());
    }
    
    @Override
    public List<Article> selectByConditionWithLimit(ArticleConditionDto articleCondition, int startIndex, int pageSize) {
        StringBuilder sqlBuilder = new StringBuilder("SELECT * FROM tb_article WHERE 1=1");
        List<Object> params = new ArrayList<>();
        
        if (articleCondition.getUserId() != null) {
            sqlBuilder.append(" AND user_id = ?");
            params.add(articleCondition.getUserId());
        }
        
        if (articleCondition.getTitle() != null && !articleCondition.getTitle().isEmpty()) {
            sqlBuilder.append(" AND title LIKE ?");
            params.add("%" + articleCondition.getTitle() + "%");
        }
        
        if (articleCondition.getContent() != null && !articleCondition.getContent().isEmpty()) {
            sqlBuilder.append(" AND content LIKE ?");
            params.add("%" + articleCondition.getContent() + "%");
        }
        
        if (articleCondition.getStatus() != null) {
            sqlBuilder.append(" AND status = ?");
            params.add(articleCondition.getStatus());
        }
        
        if (articleCondition.getCategoryId() != null) {
            sqlBuilder.append(" AND category_id = ?");
            params.add(articleCondition.getCategoryId());
        }
        
        sqlBuilder.append(" LIMIT ?, ?");
        params.add(startIndex);
        params.add(pageSize);
        
        return jdbcTemplate.query(sqlBuilder.toString(), articleRowMapper, params.toArray());
    }


    /**
     *  RowMapper接口的实现类，用于将查询结果映射为Article对象
     */

    private static class ArticleRowMapper implements RowMapper<Article> {
        @Override
        public Article mapRow(ResultSet rs, int rowNum) throws SQLException {
            /**
             * 结果封装逻辑
             */
            Article article = new Article();
            article.setId(rs.getInt("id"));
            article.setUserId(rs.getInt("user_id"));
            article.setTitle(rs.getString("title"));
            article.setContent(rs.getString("content"));
            article.setStatus(rs.getInt("status"));
            article.setDescription(rs.getString("description"));
            article.setCategoryId(rs.getInt("category_id"));
            article.setCreateTime(rs.getTimestamp("create_time").toLocalDateTime());
            article.setUpdateTime(rs.getTimestamp("update_time").toLocalDateTime());
            article.setSupport(rs.getInt("support"));
            article.setOppose(rs.getInt("oppose"));
            article.setRecommended(rs.getBoolean("recommended"));
            article.setIsTop(rs.getBoolean("is_top"));
            article.setCoverImg(rs.getString("cover_img"));
            return article;
        }
    }

}